/***************************************************************************
 *   Copyright (C) 2008 by Chris Vickery   *
 *   chrisinajar@gmail.com   *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/
#include "mainwindow.h"

#include "eventreceiver.h"
#include "irrwindow.h"

#include <QApplication>
#include <QDesktopWidget>
#include <QTimer>
#include <QDebug>
#include <QPointer>

using namespace irr;
using namespace core;
using namespace scene;
using namespace video;
using namespace io;
using namespace gui;

// This is the interval, in seconds, that we should calculate frames per second.
#define FPS_DELAY 5

QPointer<MainWindow> mainwindow_instance;

/*
This class is the main drawing class, while Qt is idling this is running. This allows drawing to happen all the time while Qt is doing it's thing. That also means that if there is something that will consume a lot of time on the event loop then, for the love of god, thread it or find a way to segment it up. Long waits on the event loop will quickly result in lagged game place. Network stuff is on another thread, so network timeouts aren't a problem.
*/
MainWindow::MainWindow(QObject *parent) : QObject(parent) {
	width=QApplication::desktop()->screenGeometry().width();
	height=QApplication::desktop()->screenGeometry().height();
	
	EventReceiver* eventr = new EventReceiver(this);
	connect(eventr,SIGNAL(closeApp()),this,SLOT(closeApp()));	
	
	qDebug() << "Creating the window at" << width << "x" << height << "x 16 in fullscreen mode.";
	width*=0.75;
	height*=0.75;
	IrrWindow* window=new IrrWindow(QApplication::desktop());
	window->show();
	SIrrlichtCreationParameters param;
	WId windowid=(window->window()->winId());
	qDebug() <<  (void*)windowid;
	param.WindowId =  (void*)windowid;
	param.DriverType = EDT_OPENGL;
	param.EventReceiver=eventr;
	param.WindowSize=dimension2d<s32>(width, height);
	
	device = irr::createDeviceEx(param);
	window->setupUi(window);
	window->resize(width,height);
	window->setMinimumSize(width,height);
	window->setMaximumSize(width,height);
	QPalette pal(QApplication::palette());
	pal.setColor(QPalette::Window,QColor(12,12,12,0));
	QApplication::setPalette(pal);
	window->label->setBackgroundRole(QPalette::NoRole);
	device->setWindowCaption(L"Necromunda 3D");
	driver = device->getVideoDriver();
	smgr = device->getSceneManager();
	guienv = device->getGUIEnvironment();
	
	guienv->addStaticText(L"Necromunda 3d", rect<s32>(((width/2)-50),80,((width/2)+50),180), false);
	guienv->addStaticText(L"FPS: ", rect<s32>(0,80,0,180), false);
	
	// This isn't even needed yet... but it's definitely there...
	smgr->addCameraSceneNode(0, vector3df(0,30,-40), vector3df(0,5,0));
	QTimer* t = new QTimer(this);
	t->setInterval(0);
	connect(t,SIGNAL(timeout()),this,SLOT(runLoop()));
	t->start();
	
	// The init function exists because this needs to return before the global object works, if it doesn't then it enters a loop and infinitely opens new windows.
	QTimer::singleShot(0,this,SLOT(init()));
}

// Do initialization stuff here... Runs after the constructor...
void MainWindow::init() {
	showMainMenu(); //Setup the main menu...
}

// This function is used to make the MainWindow class global. To reference to this class, use MWindow()...
MainWindow* MainWindow::instance() {
	if(mainwindow_instance.isNull())
		mainwindow_instance=new MainWindow(qApp);
	return mainwindow_instance;
}

/* SLOTS */
// This is the main irrlicht event loop. Anything that needs to be done every frame should happen here.
// DO NOT do non-gui event things in here. It loops really unreliably, depending greatly on hardware. If you need something to happen regularly use a QTimer with the interval that you need. This loop is entirely just for drawing on the screen, hence the FPS counter.
// Because this event loop is simply attached to a QTimer with a 0 interval, it will constantly run whenever the event loop isn't doing something. This is important to keep in mind, because if you have a task that will take a while to run, it will BLOCK the gui from updating. There is nothing more annoying than a gui that freezes while things are being computer... processEvents is a good way to prevent that, as is threading. Be really careful about threading though, seriosuly.
void MainWindow::runLoop() {
	if(!device->run()) {
		qApp->quit();
		return;
	}
	driver->beginScene(true, true, SColor(255,100,101,140));
	smgr->drawAll();
	guienv->drawAll();
	driver->endScene();
	device->yield();
}

// This class loads the buttons for the main menu, it also connects all the necesary signals/slots...
void MainWindow::showMainMenu() {
	// Clean up any existing menus
	emit clearMenu();
}

// This class loads the buttons for the testing menu, it also connects all the necesary signals/slots...
void MainWindow::showMenu2() {
	// Clean up any existing menus
	emit clearMenu();
}

void MainWindow::closeApp() {
	qDebug() << "Closing the application";
	device->closeDevice();
	disconnect(this,SLOT(runLoop()));
	qApp->quit();
}

MainWindow::~MainWindow() {
	device->drop();
}
